package com.tianji.learning.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tianji.api.cache.CategoryCache;
import com.tianji.api.client.course.CatalogueClient;
import com.tianji.api.client.course.CourseClient;
import com.tianji.api.client.search.SearchClient;
import com.tianji.api.client.user.UserClient;
import com.tianji.api.dto.course.CataSimpleInfoDTO;
import com.tianji.api.dto.course.CourseFullInfoDTO;
import com.tianji.api.dto.course.CourseSimpleInfoDTO;
import com.tianji.api.dto.user.UserDTO;
import com.tianji.common.domain.dto.PageDTO;
import com.tianji.common.utils.BeanUtils;
import com.tianji.common.utils.UserContext;
import com.tianji.learning.domain.dto.QuestionFormDTO;
import com.tianji.learning.domain.po.InteractionQuestion;
import com.tianji.learning.domain.po.InteractionReply;
import com.tianji.learning.domain.vo.QuestionAdminVO;
import com.tianji.learning.domain.vo.QuestionVO;
import com.tianji.learning.enums.QuestionStatus;
import com.tianji.learning.mapper.InteractionQuestionMapper;
import com.tianji.learning.mapper.InteractionReplyMapper;
import com.tianji.learning.query.QuestionAdminPageQuery;
import com.tianji.learning.query.QuestionPageQuery;
import com.tianji.learning.service.IInteractionQuestionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 互动提问的问题表 服务实现类
 * </p>
 *
 * @author gml
 * @since 2024-06-25
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class InteractionQuestionServiceImpl extends ServiceImpl<InteractionQuestionMapper, InteractionQuestion> implements IInteractionQuestionService {

    private final UserClient userClient;
    private final InteractionReplyMapper replyMapper;
    private final SearchClient searchClient;
    private final CourseClient courseClient;
    private final CatalogueClient catalogueClient;
    private final CategoryCache categoryCache;
    @Override
    public void saveQuestion(QuestionFormDTO questionDTO) {
        log.info("保存互动提问问题：{}", questionDTO);
        //1.转换po
        InteractionQuestion question = BeanUtil.toBean(questionDTO, InteractionQuestion.class);
        //2.添加当前用户id
        question.setUserId(UserContext.getUser());
        //3.保存
        save(question);
        //
    }

    @Override
    public PageDTO<QuestionVO> getQuestionPage(QuestionPageQuery query) {
        log.info("分页查询互动提问问题：{}", query);
        //参数校验
        Long courseId = query.getCourseId();
        Long sectionId = query.getSectionId();
        if (ObjectUtil.isEmpty(courseId) && ObjectUtil.isEmpty(sectionId)) {
            throw new RuntimeException("课程id和章id不能同时为空");
        }
        //1.分页查询
        Page<InteractionQuestion> page = lambdaQuery()
                .select(InteractionQuestion.class, field -> !field.getColumn().equals("description"))
                .eq(ObjectUtil.isNotEmpty(query.getCourseId()), InteractionQuestion::getCourseId, query.getCourseId())
                .eq(ObjectUtil.isNotEmpty(query.getSectionId()), InteractionQuestion::getSectionId, query.getSectionId())
                .eq(query.getOnlyMine(), InteractionQuestion::getUserId, UserContext.getUser())
                .page(query.toMpPageDefaultSortByCreateTimeDesc());
        List<InteractionQuestion> records = page.getRecords();
        if (ObjectUtil.isEmpty(records)){
            return PageDTO.empty(page);
        }
        //2.补充信息查询
        HashSet<Long> latestReplyIds = new HashSet<>();
        HashSet<Long> userIds = new HashSet<>();
        for (InteractionQuestion record : records) {
            if(!record.getAnonymity()){
                userIds.add(record.getUserId());
            }
            latestReplyIds.add(record.getLatestAnswerId());
        }
        //2.1获取最新的回答
        HashMap<Long, InteractionReply> latestReplyMap = new HashMap<>();
        if (!latestReplyIds.isEmpty()){
            List<InteractionReply> interactionReplies = replyMapper.selectBatchIds(latestReplyIds);
            //将interactionReplies中的id为key，用户id为value转为map
            for (InteractionReply interactionReply : interactionReplies) {
                latestReplyMap.put(interactionReply.getId(), interactionReply);
                if(!interactionReply.getAnonymity()){
                    userIds.add(interactionReply.getUserId());//将最佳回答的非匿名userId添加到userIds
                }
            }
        }
        //2.2远程调用获取用户信息
        Map<Long, UserDTO> userMap = new HashMap<>();
        if (!userIds.isEmpty()){
            List<UserDTO> userInfos = userClient.queryUserByIds(userIds);
            if (ObjectUtil.isNotEmpty(userInfos)){
                userMap = userInfos.stream().collect(Collectors.toMap(UserDTO::getId, Function.identity()));
            }
        }

        //将userDTOS中的id为key，用户信息为value转为map

        //3.遍历分页数据，封装vo
        List<QuestionVO> questionVOS = new ArrayList<>(records.size());
        for (InteractionQuestion record : records) {
            //3.1添加数据
            QuestionVO questionVO = BeanUtils.copyBean(record, QuestionVO.class);
            //3.2补充提问者信息
            if (!record.getAnonymity()){
                UserDTO userDTO = userMap.get(record.getUserId());
                if (ObjectUtil.isNotEmpty(userDTO)){
                    questionVO.setUserName(userDTO.getName());
                    questionVO.setUserIcon(userDTO.getIcon());
                }
            }
            //3.3补充最后一次回答信息
            InteractionReply interactionReply = latestReplyMap.get(record.getLatestAnswerId());
            if (ObjectUtil.isNotEmpty(interactionReply)){
                questionVO.setLatestReplyContent(interactionReply.getContent());
                if (!interactionReply.getAnonymity()){
                    UserDTO userDTO = userMap.get(interactionReply.getUserId());
                    if (ObjectUtil.isNotEmpty(userDTO)){
                        questionVO.setLatestReplyUser(userDTO.getName());
                    }
                }
            }
            questionVOS.add(questionVO);
        }
        //4.组装返回
        return PageDTO.of(page, questionVOS);
    }

    @Override
    public InteractionQuestion getQuestionById(Long id) {
        if (ObjectUtil.isEmpty(id)){
            return null;
        }
        InteractionQuestion id1 = this.query()
                .eq("id", id)
                .one();
        log.info("查询互动提问问题：{}", id1);
        if (ObjectUtil.isNotEmpty(id1)){
            return id1;
        }
        return null;
    }

    /**
     * 管理端分页条件查询互动提问的问题
     * @param query
     * @return
     */
    @Override
    public PageDTO<QuestionAdminVO> getAdminQuestionPage(QuestionAdminPageQuery query) {
        log.info("分页查询互动提问问题：{}", query);
        //1.调用es查询课程ids
        List<Long> courseIds = new ArrayList<>();
        if (ObjectUtil.isNotEmpty(query.getCourseName())){
            courseIds = searchClient.queryCoursesIdByName(query.getCourseName());
            if (ObjectUtil.isEmpty(courseIds)){
                return PageDTO.empty(0l, 0l);
            }
        }
        //1.分页查询
        Page<InteractionQuestion> page = lambdaQuery()
                .eq(ObjectUtil.isNotEmpty(query.getStatus()), InteractionQuestion::getStatus, query.getStatus())
                .ge(ObjectUtil.isNotEmpty(query.getBeginTime()), InteractionQuestion::getCreateTime, query.getBeginTime())
                .le(ObjectUtil.isNotEmpty(query.getEndTime()), InteractionQuestion::getCreateTime, query.getEndTime())
                .in(ObjectUtil.isNotEmpty(courseIds), InteractionQuestion::getCourseId, courseIds)
                .page(query.toMpPageDefaultSortByCreateTimeDesc());
        List<InteractionQuestion> records = page.getRecords();
        if (ObjectUtil.isEmpty(records)){
            return PageDTO.empty(page);
        }

        //2.补充信息查询
        //2.1远程调用获取课程信息
        Set<Long> courseIds1 = records.stream().map(InteractionQuestion::getCourseId).collect(Collectors.toSet());
        Map<Long, CourseSimpleInfoDTO> courseMap = new HashMap<>();
        if (ObjectUtil.isNotEmpty(courseIds1)){
            List<CourseSimpleInfoDTO> simpleInfoList = courseClient.getSimpleInfoList(courseIds1);
            if (ObjectUtil.isNotEmpty(simpleInfoList)){
                courseMap = simpleInfoList.stream().collect(Collectors.toMap(CourseSimpleInfoDTO::getId, Function.identity()));
            }
        }
        //2.2远程调用获取所属章节信息
        List<Long> chapterSectionIds = new ArrayList<>();
        Map<Long, CataSimpleInfoDTO> cataSimpleInfoDTOMap = new HashMap<>();
        for (InteractionQuestion record : records) {
            if (ObjectUtil.isNotEmpty(record.getChapterId())){
                chapterSectionIds.add(record.getChapterId());
            }
            if (ObjectUtil.isNotEmpty(record.getSectionId())){
                chapterSectionIds.add(record.getSectionId());
            }
            if (ObjectUtil.isNotEmpty(chapterSectionIds)){
                List<CataSimpleInfoDTO> cataSimpleInfoDTOS = catalogueClient.batchQueryCatalogue(chapterSectionIds);
                if (ObjectUtil.isNotEmpty(cataSimpleInfoDTOS)){
                    cataSimpleInfoDTOMap = cataSimpleInfoDTOS.stream().collect(Collectors.toMap(CataSimpleInfoDTO::getId, Function.identity()));
                }
            }
        }

        //2.3远程调用获取提问者信息
        Set<Long> userIds = records.stream().map(InteractionQuestion::getUserId).collect(Collectors.toSet());
        Map<Long, UserDTO> userMap = new HashMap<>();
        if (ObjectUtil.isNotEmpty(userIds)){
            userMap = userClient.queryUserByIds(userIds).stream().collect(Collectors.toMap(UserDTO::getId, Function.identity()));
        }
        //3.遍历分页数据，封装vo
        List<QuestionAdminVO> voList = new ArrayList<>();
        for (InteractionQuestion record : records) {
            QuestionAdminVO vo = BeanUtils.copyBean(record, QuestionAdminVO.class);
            //3.1补充课程信息
            CourseSimpleInfoDTO courseSimpleInfoDTO = courseMap.get(record.getCourseId());
            if (ObjectUtil.isNotEmpty(courseSimpleInfoDTO)){
                vo.setCourseName(courseSimpleInfoDTO.getName());
            }
            //3.2补充章信息
            CataSimpleInfoDTO cataSimpleInfoDTO = cataSimpleInfoDTOMap.get(record.getChapterId());
            log.info("章信息：{}", cataSimpleInfoDTO);
            if (ObjectUtil.isNotEmpty(cataSimpleInfoDTO)){
                vo.setChapterName(cataSimpleInfoDTO.getName());
            }
            //3.3补充节信息
            CataSimpleInfoDTO cataSimpleInfoDTO2 = cataSimpleInfoDTOMap.get(record.getSectionId());
            log.info("节信息：{}", cataSimpleInfoDTO2);
            if (ObjectUtil.isNotEmpty(cataSimpleInfoDTO)){
                vo.setSectionName(cataSimpleInfoDTO2.getName());
            }

            //3.4补充提问者信息
            UserDTO userDTO = userMap.get(record.getUserId());
            if (ObjectUtil.isNotEmpty(userDTO)){
                vo.setUserName(userDTO.getName());
            }
            //3.5远程调用分类名称拼接
            ArrayList<Long> list = new ArrayList<>();
            CourseSimpleInfoDTO courseInfo = courseMap.get(record.getCourseId());
            if (ObjectUtil.isNotEmpty(courseInfo)){
                list.add(courseInfo.getFirstCateId());
                list.add(courseInfo.getSecondCateId());
                list.add(courseInfo.getThirdCateId());
            }
            List<String> categoryNameList = categoryCache.getCategoryNameList(list);
            log.info("远程调用分类名称拼接：{}", categoryNameList);
            if (ObjectUtil.isNotEmpty(categoryNameList)){
                for (String s : categoryNameList) {
                    vo.setCategoryName(s);
                }
            }
            voList.add(vo);
        }
        //4.组装返回
        return PageDTO.of(page, voList);
    }

    /**
     * 管理端根据id查询互动提问的问题
     * @param id
     * @return
     */
    @Override
    public QuestionAdminVO getAdminQuestionById(Long id) {
        //1.查询问题信息并将问题状态改为已查看
        InteractionQuestion questionById = this.getQuestionById(id);
        if (ObjectUtil.isNotEmpty(questionById)){
            questionById.setStatus(QuestionStatus.CHECKED);
            this.updateById(questionById);
        }
        //2.补全信息
        //2.1远程调用查询课程信息
        CourseFullInfoDTO courseInfoById = new CourseFullInfoDTO();
        if (ObjectUtil.isNotEmpty(questionById.getCourseId())){
            courseInfoById = courseClient.getCourseInfoById(questionById.getCourseId(), true, true);
        }
        //2.2远程调用获取课程老师信息
        List<UserDTO> teacher = new ArrayList<>();
        if(ObjectUtil.isNotEmpty(courseInfoById)){
            List<Long> teacherIds = courseInfoById.getTeacherIds();
            if (ObjectUtil.isNotEmpty(teacherIds)){
                teacher = userClient.queryUserByIds(teacherIds);
            }
        }
        //2.3远程调用获取课程分类信息
        List<String> categoryNameList = new ArrayList<>();
        if (ObjectUtil.isNotEmpty(courseInfoById)){
            List<Long> categoryIds = courseInfoById.getCategoryIds();
            if (ObjectUtil.isNotEmpty(categoryIds)){
                categoryNameList = categoryCache.getCategoryNameList(categoryIds);
            }
        }
        //2.4远程调用获取所属章节信息
        List<Long> list = new ArrayList<>();
        Map<Long, CataSimpleInfoDTO> cataInfoMap = new HashMap<>();
        if (ObjectUtil.isNotEmpty(questionById.getChapterId())){
            list.add(questionById.getChapterId());
        }
        if (ObjectUtil.isNotEmpty(questionById.getSectionId())){
            list.add(questionById.getSectionId());
        }
        List<CataSimpleInfoDTO> cataInfo = catalogueClient.batchQueryCatalogue(list);
        if (ObjectUtil.isNotEmpty(cataInfo)){
            cataInfoMap = cataInfo.stream().collect(Collectors.toMap(CataSimpleInfoDTO::getId, Function.identity()));
        }
        //2.5远程调用获取提问者信息
        UserDTO userById = new UserDTO();
        if (ObjectUtil.isNotEmpty(questionById.getUserId())){
            userById = userClient.queryUserById(questionById.getUserId());
        }

        //3.封装vo
        QuestionAdminVO vo = BeanUtils.copyBean(questionById, QuestionAdminVO.class);
        //3.1补充课程名
        if (ObjectUtil.isNotEmpty(courseInfoById.getName())){
            vo.setCourseName(courseInfoById.getName());
        }
        //3.2补充课程分类
        if (ObjectUtil.isNotEmpty(categoryNameList)){
            vo.setCategoryName(categoryNameList.get(0));
        }
        //3.3补充章
        if (ObjectUtil.isNotEmpty(cataInfoMap)){
            CataSimpleInfoDTO cataSimpleInfoDTO = cataInfoMap.get(questionById.getChapterId());
            if (ObjectUtil.isNotEmpty(cataSimpleInfoDTO)){
                vo.setChapterName(cataSimpleInfoDTO.getName());
            }
        }
        //3.4补充节
        if (ObjectUtil.isNotEmpty(cataInfoMap)){
            CataSimpleInfoDTO cataSimpleInfoDTO = cataInfoMap.get(questionById.getSectionId());
            if (ObjectUtil.isNotEmpty(cataSimpleInfoDTO)){
                vo.setSectionName(cataSimpleInfoDTO.getName());
            }
        }
        //3.5补充老师
        if (ObjectUtil.isNotEmpty(teacher)){
            vo.setTeacherName( teacher.get(0).getName());
        }
        //3.6补充提问者
        if (ObjectUtil.isNotEmpty(userById)){
            vo.setUserName(userById.getName());
            vo.setUserIcon(userById.getIcon());
        }
        return vo;
    }

    @Override
    public void updateHidden(Long id, Boolean hidden) {
        this.update().set("hidden", hidden).eq("id", id).update();
    }
}
